use std::fmt::{Display, Formatter, write};
use std::ops::Add;

/// 标准库的常用特征
/// Default, Debug, PartialEq, Eq, Copy, Clone
/// std::ops模块的 Add 特征
/// std::convert的 Into/From 特征
/// Display

// 自动实现标准库的Default特征
#[derive(Default, Debug, PartialEq, Copy, Clone)]
struct Complex<T> {
    // 实部
    re: T,

    // 虚部
    im: T,
}

impl<T> Complex<T> {
    fn new(re: T, im: T) -> Self {
        Complex { re, im }
    }
}

impl<T: Add<T, Output=T>> Add for Complex<T> {
    type Output = Complex<T>;
    fn add(self, rhs: Self) -> Self::Output {
        Complex { re: self.re + rhs.re, im: self.im + rhs.im }
    }
}

impl<T> From<(T, T)> for Complex<T> {
    fn from(value: (T, T)) -> Self {
        Complex { re: value.0, im: value.1 }
    }
}

impl<T: Display> Display for Complex<T> {
    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
        write!(f, "{} + {}i", self.re, self.im)
    }
}

// 测试代码
#[cfg(test)]
mod tests {
    use super::Complex;

    #[test]
    fn complex_basics() {
        let first = Complex::new(3, 5);
        let second: Complex<i32> = Complex::default();
        assert_eq!(first.re, 3);
        assert_eq!(first.im, 5);
        assert!(second.re == second.im);
    }

    #[test]
    fn complex_addition() {
        let a = Complex::new(1, -2);
        let b = Complex::default();
        let res = a + b;
        assert_eq!(res, a);
    }

    #[test]
    fn complex_from() {
        let a = (234, 456);
        let complex = Complex::from(a);
        assert_eq!(complex.re, 234);
        assert_eq!(complex.im, 456);
    }

    ///  cargo test -- --nocapture 
    #[test]
    fn complex_display() {
        let c = Complex::new(234, 456);
        println!("{}", c);
    }
}